package com.witframework.soa.util;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.List;
import java.util.Map;

import com.witframework.util.BeanUtils;

public class ClassTypeUtil {
	public static boolean isPrimitiveType(Class type) {
		if (type == String.class || type == Double.TYPE || type == Float.TYPE
				|| type == Integer.TYPE || type == Character.TYPE
				|| type == Byte.TYPE || type == Short.TYPE || type == Long.TYPE
				|| type == Boolean.TYPE || type == Void.TYPE) {
			return true;
		}
		return false;
	}

	public static boolean isPrimitiveType(String typeString) {
		if (typeString.equals("String") || typeString.equals("Character")
				|| typeString.equals("Integer") || typeString.equals("Double")
				|| typeString.equals("Float") || typeString.equals("Char")
				|| typeString.equals("Long") || typeString.equals("Short")
				|| typeString.equals("Byte") || typeString.equals("Boolean")) {
			return true;
		}
		return false;
	}

	public static boolean isBasePrimitiveType(String typeString) {
		if (typeString.equalsIgnoreCase("int")
				|| typeString.equalsIgnoreCase("double")
				|| typeString.equalsIgnoreCase("float")
				|| typeString.equalsIgnoreCase("char")
				|| typeString.equalsIgnoreCase("long")
				|| typeString.equalsIgnoreCase("short")
				|| typeString.equalsIgnoreCase("byte")
				|| typeString.equalsIgnoreCase("boolean")) {
			return true;
		}
		return false;
	}

	public static Class getPrimitiveType(String typeString) {
		if (typeString.equals("int"))
			return Integer.TYPE;
		else if (typeString.equals("Integer"))
			return Integer.class;
		else if (typeString.equals("double"))
			return Double.TYPE;
		else if (typeString.equals("Double"))
			return Double.class;
		else if (typeString.equals("float"))
			return Float.TYPE;
		else if (typeString.equals("Float"))
			return Float.class;
		else if (typeString.equals("long"))
			return Long.TYPE;
		else if (typeString.equals("Long"))
			return Long.class;
		else if (typeString.equals("short"))
			return Short.TYPE;
		else if (typeString.equals("Short"))
			return Short.class;
		else if (typeString.equals("byte"))
			return Byte.TYPE;
		else if (typeString.equals("Byte"))
			return Byte.class;
		else if (typeString.equals("boolean"))
			return Boolean.TYPE;
		else if (typeString.equals("boolean"))
			return Boolean.class;
		else if (typeString.equals("char"))
			return Character.TYPE;
		else if (typeString.equals("Character"))
			return Character.class;
		else if (typeString.equals("String"))
			return String.class;
		return Void.TYPE;
	}

	public static boolean isBaseType(Class type) {
		if (type == String.class || type == Integer.class
				|| type == Double.class || type == Float.class
				|| type == Byte.class || type == Character.class)
			return true;
		return false;
	}

	public static boolean isNumber(String typeName) {
		if (typeName == null)
			return false;
		if (typeName.equals("int")
				|| typeName.equals("Integer") || typeName.equals("float")
				|| typeName.equals("Float") || typeName.equals("double")
				|| typeName.equals("Double") || typeName.equals("short")
				|| typeName.equals("Short") || typeName.equals("long")
				|| typeName.equals("Long"))
			return true;
		return false;
	}
	public static boolean isByte(String typeName){
		if (typeName == null)
			return false;
		if (typeName.equals("byte"))
			return true;
		return false;
	}

	public static Object createPrimitiveValue(String strValue, String type) {
		Object value = null;
		try {
			if (type.equalsIgnoreCase("String")) {
				value = strValue;
			} else if (type.equalsIgnoreCase("Character")) {
				if (strValue.length() >= 1) {
					value = new Character(strValue.charAt(0));
				}
			} else if (type.equalsIgnoreCase("char")) {
				if (strValue.length() >= 1) {
					value = new Character(strValue.charAt(0)).charValue();
				}
			} else if (type.equals("Integer")) {
				value = new Integer(strValue);
			} else if (type.equals("int")) {
				value = new Integer(strValue).intValue();
			} else if (type.equals("Short")) {
				value = new Short(strValue);
			} else if (type.equals("short")) {
				value = new Short(strValue).shortValue();
			} else if (type.equals("Long")) {
				value = new Long(strValue);
			} else if (type.equals("long")) {
				value = new Long(strValue).longValue();
			} else if (type.equals("Float")) {
				value = new Float(strValue);
			} else if (type.equals("float")) {
				value = new Float(strValue).floatValue();
			} else if (type.equals("Double")) {
				value = new Double(strValue);
			} else if (type.equals("double")) {
				value = new Double(strValue).doubleValue();
			} else if (type.equals("Byte")) {
				value = new Byte(strValue);
			} else if (type.equals("byte")) {
				value = new Byte(strValue).byteValue();
			} else if (type.equals("Boolean")) {
				value = new Boolean(strValue);
			} else if (type.equals("boolean")) {
				value = new Boolean(strValue).booleanValue();
			}
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
		return value;
	}

	private static Object newBasePrimitiveObject(String primitiveTYpe) {
		if (primitiveTYpe.equals("int"))
			return new Integer(0).intValue();
		else if (primitiveTYpe.equals("double"))
			return new Double(0).intValue();
		else if (primitiveTYpe.equals("char"))
			return ' ';
		else if (primitiveTYpe.equals("byte"))
			return 0;
		else if (primitiveTYpe.equals("long"))
			return 0l;
		else if (primitiveTYpe.equals("short"))
			return 0;
		else if (primitiveTYpe.equals("boolean"))
			return false;
		return new Object();
	}

	public static Object newObject(String objectClassName) {
		Object object = null;
		if (ClassTypeUtil.isBasePrimitiveType(objectClassName)) {
			object = newBasePrimitiveObject(objectClassName);
		}		
		else if (objectClassName != null) {
			if (ClassTypeUtil.isPrimitiveType(objectClassName)) {
				object = ClassTypeUtil.createPrimitiveValue("0",
						objectClassName);
			} else {
				try {
					object = Class.forName(objectClassName).newInstance();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
		return object;
	}

	/**
	 * 首先通过Getter方法获取属性的值，如果没有Getter方法，则直接取值。
	 * 
	 * @param object
	 * @param propertyName
	 * @return
	 */
	public static Object getFieldValue(Object object, String propertyName) {
		
		try {
			BeanInfo beanInfo =Introspector.getBeanInfo (object.getClass (), Object.class);
			PropertyDescriptor[] beanProperties =beanInfo.getPropertyDescriptors ();
			 for (int i = 0; i < beanProperties.length; i++){
				 if (beanProperties[i].getReadMethod () == null){
	                    continue;
	             }
				 String name = beanProperties[i].getName ();
				 if(name.equals(propertyName)){
					 beanProperties[i].getReadMethod().invoke(object, null);
					 return beanProperties[i].getReadMethod().invoke(object, null);
				 }
			 }
		} catch (Exception e) {
			
		}
		try {
			return BeanUtils.getDeclaredProperty(object, propertyName);
		} catch (Exception e) {
			return null;
		}
	}

	public static void setBeanPropertyValue(Object bean, String propertyName,
			Object newValue) {
		try {
			BeanInfo beanInfo =Introspector.getBeanInfo (bean.getClass (), Object.class);
			PropertyDescriptor[] beanProperties =beanInfo.getPropertyDescriptors ();
			 for (int i = 0; i < beanProperties.length; i++){
				 if (beanProperties[i].getWriteMethod () == null){
	                    continue;
	             }
				 String name = beanProperties[i].getName ();
				 if(name.equals(propertyName)){
					 beanProperties[i].getWriteMethod().invoke(bean, newValue);
					 break;
				 }
			 }
		} catch (Exception e) {
			
		}
		try {
			if (List.class.isInstance(bean)) {
				((List) bean).add(newValue);
			} else if (Map.class.isInstance(bean)) {
				((Map) bean).put(propertyName, newValue);
			} else {
				BeanUtils.setDeclaredProperty(bean, propertyName, newValue);
			}
		} catch (Exception e) {
			// e.printStackTrace();
		}
	}
	public static boolean isCustomType(String elementTypeString){
		return !(isPrimitiveType(elementTypeString)
				||isBasePrimitiveType(elementTypeString)
				||elementTypeString.equals("arrays")
				||elementTypeString.startsWith("java.util"));
	}
}
